using System;
using System.Collections.Generic;
using System.IO;
using Godot;
using GoGameClient.script.resources;
using Newtonsoft.Json;

namespace GoGameClient.script.global;

public class ResourcesControl
{
    public static string RootPath => "res://resources/";
    private static string Info { get; } = RootPath + "info/";
    private MapResources _mapBaseResources;
    private MapResources _mapMaskResources;
    private readonly RoleResources _roleResources = new();
    private readonly Dictionary<int, TerrainResources> _terrainResourcesMap = new();
    private readonly Dictionary<int, MapInfo> _mapInfoResourcesMap = new();
    private static ResourcesControl _control;
    public int CurrentMapId;


    public RoleResources GetRoleResources()
    {
        return _roleResources;
    }

    public static ResourcesControl Instance()
    {
        return _control ??= new ResourcesControl();
    }

    public void InitMapinfo(Action<int> call)
    {
        var directoryInfo = new DirectoryInfo("resources/info");
        if (!directoryInfo.Exists)
        {
            throw new Exception($"获取文件目录不存在");
        }

        call(10);
        // 获取目录下的所有文件和子目录的名称  
        var files = directoryInfo.GetFiles();
        foreach (var fileInfo in files)
        {
            var resource = (Json)GD.Load($"{Info}/{fileInfo.Name}");
            if (resource == null)
            {
                continue;
            }

            var mapInfo = JsonConvert.DeserializeObject<MapInfo>(Json.Stringify(resource.Data));
            if (mapInfo == null)
            {
                continue;
            }

            _mapInfoResourcesMap.Add(int.Parse(Path.GetFileNameWithoutExtension(fileInfo.Name)), mapInfo);
        }

        call(20);
        var initInfo =
            JsonConvert.DeserializeObject<InitInfo>(Json.Stringify(((Json)GD.Load(RootPath + "init.json")).Data));
        var count = 5;
        foreach (var terrainId in initInfo.Terrain)
        {
            _terrainResourcesMap.Add(terrainId, new TerrainResources(terrainId));
            call(30 + count++ * 10);
        }
    }

    public AStarGrid2D GetCurrentAStart()
    {
        return _terrainResourcesMap.GetValueOrDefault(CurrentMapId).GetAStarGrid2D();
    }

    public void SetMapResources(int id)
    {
        CurrentMapId = id;
        _mapBaseResources = new MapResources(id);
        _mapBaseResources.SetPath("Map");
        _mapMaskResources = new MapResources(id);
        _mapMaskResources.SetPath("Mask");
        var containsKey = _terrainResourcesMap.ContainsKey(id);
        if (!containsKey)
        {
            _terrainResourcesMap.Add(id, new TerrainResources(id));
        }
    }

    public List<TileInfo> TryGetMapTile()
    {
        return _mapBaseResources.TileSetAtlasSources();
    }

    public List<TileInfo> TryGetMaskTile()
    {
        return _mapMaskResources.TileSetAtlasSources();
    }


    public void ApplyTile(Vector2I position)
    {
        _mapBaseResources.ApplyTileSource(position);
        _mapMaskResources.ApplyTileSource(position);
    }


    public MapInfo GetCurrentMapInfo()
    {
        return _mapInfoResourcesMap.GetValueOrDefault(CurrentMapId);
    }

    public MapInfo GetMapInfo(int id)
    {
        return _mapInfoResourcesMap.GetValueOrDefault(id);
    }

    public string GetRandomName()
    {
        return new RandomNameResources().GetRandomName();
    }
}

public class InitInfo
{
    public List<int> Terrain { get; } = new();
}